package org.mcjug.locationmailer.activity;

import java.util.ArrayList;
import java.util.List;

import org.mcjug.locationmailer.R;
import org.mcjug.locationmailer.util.EmailUtil;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.InputType;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class EmailActivity extends BaseActivity {
    private ListView listView;
    private ListAdapter listAdapter;
    private List<String> emailAddressList = new ArrayList<String>();
    private List<String> emailAddressStateList = new ArrayList<String>();
    private SharedPreferences prefs;

    // Email validation pattern
    private static final String EMAIL_PATTERN = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\." + "[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*"
            + "@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?";

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.emailaddress);

        prefs = PreferenceManager.getDefaultSharedPreferences(this);

        // Email address list
        emailAddressList = EmailUtil.getCSVList(prefs, EmailUtil.EMAIL_ADDRESS);

        // Indicates which email addresses we will send to
        emailAddressStateList = EmailUtil.getCSVList(prefs, EmailUtil.EMAIL_ADDRESS_STATE);

        // Email address list view
        listView = (ListView) findViewById(R.id.list);
        listAdapter = new ListAdapter(getApplicationContext(), R.layout.emailaddressrow, R.id.emailAddressText,
                emailAddressList);
        listView.setAdapter(listAdapter);

        // Add Email Address
        final ImageButton addButton = (ImageButton) findViewById(R.id.buttonEmailListAdd);
        addButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                getPopupDialog(getString(R.string.titleAddEmailAddress), "", true, -1).show();
            }
        });
    }

    protected void onPause() {
        super.onPause();
        unregisterForContextMenu(listView);
    }

    private void saveEmailSettings() {
        // Save changes made to the email addresses
        Editor editor = prefs.edit();
        saveListToSharedPreferences(emailAddressList, EmailUtil.EMAIL_ADDRESS, editor);
        saveListToSharedPreferences(emailAddressStateList, EmailUtil.EMAIL_ADDRESS_STATE, editor);
        editor.commit();
    }

    private void saveListToSharedPreferences(List<String> list, String prefsKey, Editor editor) {
        if (list.isEmpty()) {
            editor.remove(prefsKey);
        } else {
            editor.putString(prefsKey, EmailUtil.getCSVString(list, ","));
        }
    }

    protected void onResume() {
        super.onResume();
        registerForContextMenu(listView);
    }

    private AlertDialog.Builder getPopupDialog(String title, String emailAddress, final boolean isAdd,
            final int position) {
        AlertDialog.Builder alert = new AlertDialog.Builder(this);
        alert.setTitle(title);

        // Email Address text editor
        final EditText input = new EditText(this);
        input.setText(emailAddress);

        // Set keyboard for email address
        input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);

        // Add text view to dialog
        alert.setView(input);

        // OK Button
        alert.setPositiveButton(getString(R.string.buttonOk), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                String emailAddress = input.getText().toString();
                if (checkEmailAddressValid(emailAddress, position)) {
                    if (isAdd) {
                        emailAddressList.add(emailAddress);
                        emailAddressStateList.add(Boolean.toString(true));
                    } else {
                        emailAddressList.set(position, emailAddress);
                    }
                    saveEmailSettings();
                    listAdapter.notifyDataSetChanged();
                }
            }
        });

        // Cancel button
        alert.setNegativeButton(getString(R.string.buttonCancel), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                dialog.cancel();
            }
        });

        return alert;
    }

    private AlertDialog.Builder getDeleteConfirmPopupDialog(String emailAddressToDelete, final int position) {
        AlertDialog.Builder alert = new AlertDialog.Builder(this);
        alert.setTitle(getString(R.string.titleDeleteEmailAddress));

        // Delete Confirmation message
        String msg = String.format(getString(R.string.deleteConfirm), emailAddressToDelete);
        alert.setMessage(msg);

        // OK Button
        alert.setPositiveButton(getString(R.string.buttonOk), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                emailAddressList.remove(position);
                emailAddressStateList.remove(position);
                listAdapter.notifyDataSetChanged();
            }
        });

        // Cancel Button
        alert.setNegativeButton(getString(R.string.buttonCancel), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                dialog.cancel();
            }
        });

        return alert;
    }

    // Check if the email address is valid
    private boolean checkEmailAddressValid(String emailAddress, int position) {
        boolean isValid = true;

        // Check if email address is a valid format
        if (emailAddress == null || !emailAddress.matches(EMAIL_PATTERN)) {
            Toast.makeText(this, getString(R.string.msgEmailInvalid), Toast.LENGTH_LONG).show();
            isValid = false;

            // Check if email address is a duplicate
        } else if (isDuplicate(emailAddress, position)) {
            isValid = false;
        }

        return isValid;
    }

    // Check if the email address is a duplicate
    private boolean isDuplicate(String emailAddress, int position) {
        int idx = emailAddressList.indexOf(emailAddress);

        // If not in the list or the one in the list is the same one being modified then not a duplicate
        if (idx == -1 || idx == position) {
            return false;
        } else {
            Toast.makeText(this, getString(R.string.msgEmailExists), Toast.LENGTH_LONG).show();
            return true;
        }
    }

    // Modify/Delete Email Address menu item selection
    public boolean onContextItemSelected(MenuItem item) {
        super.onContextItemSelected(item);

        AdapterView.AdapterContextMenuInfo info;
        try {
            info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
        } catch (ClassCastException e) {
            return false;
        }

        // Get the selected email address
        String emailAddress = listAdapter.getItem(info.position);
        int itemId = item.getItemId();

        // Modify Email Address
        if (itemId == R.id.itemEmailModify) {
            // Modify Editor
            getPopupDialog(getString(R.string.titleModifyEmailAddress), emailAddress, false, info.position).show();

            // Delete Email Address
        } else if (itemId == R.id.itemEmailDelete) {
            // Delete Confirmation
            getDeleteConfirmPopupDialog(emailAddress, info.position).show();

        } else {
            return false;
        }
        return true;
    }

    // Modify/Delete Email Address menu
    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
        menu.setHeaderTitle(getString(R.string.titleEmailAddress));
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.emailmenu, menu);
        super.onCreateContextMenu(menu, view, menuInfo);
    }

    private class ListAdapter extends ArrayAdapter<String> {
        public ListAdapter(Context context, int resource, int textViewResourceId, List<String> objects) {
            super(context, resource, textViewResourceId, objects);
        }

        // Called for each row
        public View getView(final int position, View convertView, ViewGroup parent) {
            View row = convertView;
            if (row == null) {
                LayoutInflater inflater = getLayoutInflater();
                row = inflater.inflate(R.layout.emailaddressrow, parent, false);
            }

            final TextView textView = (TextView) row.findViewById(R.id.emailAddressText);
            textView.setText(emailAddressList.get(position));

            final CheckBox checkBox = (CheckBox) row.findViewById(R.id.emailAddressCheckBox);
            checkBox.setOnClickListener(new OnClickListener() {
                public void onClick(View view) {
                    CheckBox checkBox = (CheckBox) view;

                    // Set whether the email address is to be used
                    emailAddressStateList.set(position, Boolean.toString(checkBox.isChecked()));
                    saveEmailSettings();
                    listAdapter.notifyDataSetChanged();
                }
            });

            checkBox.setChecked(Boolean.parseBoolean(emailAddressStateList.get(position)));

            return row;
        }
    }
}
